/**
 * 给定一个无向图，求如下子图的总数
 * 1. 三叉
 * 2. 三链
 * 3. 三角形
 * 对于三叉，枚举点即可，假设点的度数是d，则该点的三叉数量是C(d, 3)
 * 
 * 对与三链与三角形，注意到都是有三条边连续构成，区别只在于一个封口一个不封口。
 * 枚举每一条边e:
 *    令 a2 += (d[e.u] - 1) * (d[e.v] - 1)
 * 这样就计算出了所有以e为中间边的构型的数量，a2本质上 = 链的数量 + 3倍三角形数量
 * 
 * 再计算三角形的数量，只考虑起点小终点大的边，枚举边(u, v)，则u出边与v出边的交集大小就是(u, v)能够构成的三角形数量
 * 枚举边(u, v)做一个交集操作（用bitset爆内存了）。
 * 本质上就是三元环计数，为O(MlogM)
 * 
 * 左后答案是 SIGMA{C(d, 3)} + a2 - 2倍三角形数量
 */
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;

using llt = long long;
using vi = vector<int>;
using vll = vector<llt>;
using pii = pair<int, int>;
using pll = pair<llt, llt>;

int N;
vi D;
int M;
vector<vi> G;
vector<pii> E;

void work(){
    cin >> N >> M;
    D.assign(N + 1, 0);
    G.assign(N + 1, {});
    E.assign(M, {});
    for(int a,b,i=0;i<M;++i){
        cin >> a >> b;
        if(a > b) swap(a, b);
        D[a] += 1;
        D[b] += 1;
        G[a].push_back(b);
        E[i] = {a, b};
    }
    for(auto & v : G) sort(v.begin(), v.end());

    llt a1 = 0;
    for(auto d : D){
        if(d >= 3){
            a1 += d * (d - 1LL) * (d - 2LL) / 6LL;
        }
    }
    llt a2 = 0;
    for(const auto & e : E){
        a2 += (D[e.first] - 1LL) * (D[e.second] - 1LL);
    }
    llt a3 = 0;
    for(const auto & e : E){
        vi tmp;
        set_intersection(G[e.first].begin(), G[e.first].end(), G[e.second].begin(), G[e.second].end(), back_inserter(tmp));
        a3 += tmp.size();
    }
    cout << a1 + a2 - a3 - a3 << endl;
    return;
}


int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);	
    
    int nofkase = 1;
	// cin >> nofkase;
	while(nofkase--) work();
	return 0;
}